/**
 * 统一的加载状态管理工具
 * 避免多个API调用时的加载状态冲突
 */

class LoadingManager {
  constructor() {
    this.loadingCount = 0
    this.loadingTimer = null
  }

  /**
   * 显示加载状态
   * @param {string} title - 加载提示文字
   * @param {boolean} mask - 是否显示遮罩
   */
  show(title = '加载中...', mask = true) {
    this.loadingCount++
    
    // 防抖处理，避免频繁显示/隐藏
    if (this.loadingTimer) {
      clearTimeout(this.loadingTimer)
    }
    
    this.loadingTimer = setTimeout(() => {
      if (this.loadingCount > 0) {
        uni.showLoading({
          title,
          mask
        })
      }
    }, 100)
  }

  /**
   * 隐藏加载状态
   */
  hide() {
    this.loadingCount = Math.max(0, this.loadingCount - 1)
    
    if (this.loadingTimer) {
      clearTimeout(this.loadingTimer)
    }
    
    if (this.loadingCount === 0) {
      uni.hideLoading()
    }
  }

  /**
   * 强制隐藏加载状态
   */
  forceHide() {
    this.loadingCount = 0
    if (this.loadingTimer) {
      clearTimeout(this.loadingTimer)
    }
    uni.hideLoading()
  }

  /**
   * 获取当前加载状态
   */
  isLoading() {
    return this.loadingCount > 0
  }
}

// 创建全局实例
const loadingManager = new LoadingManager()

/**
 * 带加载状态的API调用包装器
 * @param {Function} apiCall - API调用函数
 * @param {Object} options - 配置选项
 */
export const withLoading = async (apiCall, options = {}) => {
  const {
    loadingText = '加载中...',
    showLoading = true,
    mask = true
  } = options

  if (showLoading) {
    loadingManager.show(loadingText, mask)
  }

  try {
    const result = await apiCall()
    return result
  } finally {
    if (showLoading) {
      loadingManager.hide()
    }
  }
}

/**
 * 批量API调用管理
 */
export class BatchApiManager {
  constructor() {
    this.pendingCalls = new Set()
  }

  /**
   * 添加API调用
   * @param {string} key - 调用标识
   * @param {Function} apiCall - API调用函数
   * @param {Object} options - 配置选项
   */
  async add(key, apiCall, options = {}) {
    // 防止重复调用
    if (this.pendingCalls.has(key)) {
      return null
    }

    this.pendingCalls.add(key)

    try {
      const result = await withLoading(apiCall, options)
      return result
    } finally {
      this.pendingCalls.delete(key)
    }
  }

  /**
   * 检查是否有待处理的调用
   */
  hasPending(key) {
    return key ? this.pendingCalls.has(key) : this.pendingCalls.size > 0
  }

  /**
   * 清除所有待处理的调用
   */
  clear() {
    this.pendingCalls.clear()
  }
}

/**
 * 防抖API调用
 * @param {Function} apiCall - API调用函数
 * @param {number} delay - 延迟时间（毫秒）
 */
export const debounceApi = (apiCall, delay = 300) => {
  let timer = null
  
  return (...args) => {
    if (timer) {
      clearTimeout(timer)
    }
    
    return new Promise((resolve, reject) => {
      timer = setTimeout(async () => {
        try {
          const result = await apiCall(...args)
          resolve(result)
        } catch (error) {
          reject(error)
        }
      }, delay)
    })
  }
}

/**
 * 节流API调用
 * @param {Function} apiCall - API调用函数
 * @param {number} interval - 间隔时间（毫秒）
 */
export const throttleApi = (apiCall, interval = 1000) => {
  let lastCallTime = 0
  let timer = null
  
  return (...args) => {
    const now = Date.now()
    
    if (now - lastCallTime >= interval) {
      lastCallTime = now
      return apiCall(...args)
    } else {
      if (timer) {
        clearTimeout(timer)
      }
      
      return new Promise((resolve, reject) => {
        timer = setTimeout(async () => {
          lastCallTime = Date.now()
          try {
            const result = await apiCall(...args)
            resolve(result)
          } catch (error) {
            reject(error)
          }
        }, interval - (now - lastCallTime))
      })
    }
  }
}

/**
 * 重试机制
 * @param {Function} apiCall - API调用函数
 * @param {Object} options - 配置选项
 */
export const retryApi = async (apiCall, options = {}) => {
  const {
    maxRetries = 3,
    retryDelay = 1000,
    retryCondition = (error) => true
  } = options

  let lastError = null

  for (let i = 0; i <= maxRetries; i++) {
    try {
      return await apiCall()
    } catch (error) {
      lastError = error
      
      if (i === maxRetries || !retryCondition(error)) {
        throw error
      }
      
      // 等待后重试
      await new Promise(resolve => setTimeout(resolve, retryDelay * (i + 1)))
    }
  }
  
  throw lastError
}

export default loadingManager
export { loadingManager }
